home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
gawk
/
gawk213b.zoo
/
test
/
lisp
/
walk.ms
< prev
next >
Wrap
Text File
|
1991-05-21
|
15KB
|
504 lines
.\" troff -ms
.\" ...if no CW font available, change CW to B globally
.de ZB
.DS
.ft CW
.nf
..
.de ZE
.DE
.ft R
.fi
.br
..
.TL
A LISP interpreter in Awk
.AU
Roger Rohrbach
.AI
1592 Union St., #94
San Francisco, CA 94123
.ND
January 3, 1989
.AB ABSTRACT
.PP
This note describes a simple interpreter for the LISP programming
language, written in \fBawk\fR. It provides
intrinsic versions of the basic functions on s-expressions, and many others
written in LISP. It is compatible with the commonly
available version of \fBawk\fR that is
supplied with most UNIX systems. The interpreter serves to illustrate
the use of \fBawk\fR for prototyping or implementing language
translators, as well as providing a simple example of LISP
implementation techniques.
.AE
.SH
Intrinsic functions.
.PP
The interpreter has thirteen built-in functions.
These include the five elementary functions on s-expressions defined
by McCarthy [1]; some conditional expression operators; an
assignment operator, and some functions to control the evaluation process.
.PP
The intrinsic functions are summarized below.
Familiarity with existing LISP systems is assumed in the
descriptions of these functions.
.IP "\f(CW(car \fIl\fP)\fR"
.br
Returns the first element of the list \fIl\fR.
An error occurs if \fIl\fR is atomic.
.IP "\f(CW(cdr \fIl\fP)\fR"
.br
Returns the remainder of the list \fIl\fR, \fIi.e.\fR,
the sublist containing the second through the last
elements. If \fIl\fR has only one element, \fBnil\fR is
returned. \fBcdr\fR is undefined on atoms.
.IP "\f(CW(cons \fIe l\fP)\fR"
.br
Constructs a new list whose \fBcar\fR is \fIe\fR
and whose \fBcdr\fR is \fIl\fR.
.IP "\f(CW(eq \fIx y\fP)\fR"
.br
Returns \fBt\fR if \fIx\fR and \fIy\fR
are the same LISP object, \fIi.e.\fR, are either atomic and
have the same print name, or evaluate to the same
list cell. Otherwise, \fBnil\fR is returned.
.IP "\f(CW(atom \fIs\fP)\fR"
.br
Returns \fBt\fR if \fIs\fR is an atom, otherwise \fBnil\fR.
.IP "\f(CW(set \fIx y\fP)\fR"
.br
Assigns the value \fIy\fR to \fIx\fR and returns \fIy\fR.
\fIx\fR must be atomic, and may not be a constant
or name an intrinsic function.
.IP "\f(CW(eval \fIs\fP)\fR"
.br
Evaluates \fIs\fR and returns the result.
.IP "\f(CW(error \fIs\fP)\fR"
.br
Halts evaluation and returns \fBnil\fR.
The atom \fIs\fR is printed.
.IP "\f(CW(quote \fIs\fP)\fR"
.br
Returns \fIs\fR, unevaluated. The form
.ZB
\'\fIexpr\fP
.ZE
is an abbreviation for
.ZB
(quote \fIexpr\fP)
.ZE
.IP "\f(CW(cond (\fIp1 \f(CW[\fIe1\f(CW]) \fI...\fP (\fIpN \f(CW[\fIeN\f(CW]))\fR"
.br
Evaluates each \fIp\fR from left to right. If any
evaluate to a value other than \fBnil\fR, the
corresponding \fIe\fR is evaluated and the result is returned.
If there is no corresponding \fIe\fR, the value of the \fIp\fR
itself is returned instead.
If no \fIp\fR has a non-null value, \fBnil\fR is returned.
.IP "\f(CW(and \fIe1 ... eN\fP)\fR"
.br
Evaluates each \fIe\fR and returns \fBnil\fR if any evaluate to \fBnil\fR.
Otherwise the value of the last \fIe\fR is returned.
.IP "\f(CW(or \fIe1 ... eN\fP)\fR"
.br
Evaluates each \fIe\fR and returns the first whose
value is non-null. If no such \fIe\fR is found, \fBnil\fR is returned.
.IP "\f(CW(list \fIe1 ... eN\fP)\fR"
.br
Constructs a new list with elements \fIe1 ... eN\fR.
Equivalent to
.br
\f(CW(cons \fIe1\fP (cons \fI...\fP (cons \fIeN\fP nil)\fR.
.SH
Lambda functions.
.PP
The following functions are written in LISP and are
defined in the file \fBwalk.w\fR. Most of
these are commonly supplied with LISP systems.
.IP "\f(CW(cadr \fIs\fP)\fR"
.IP "\f(CW(cddr \fIs\fP)\fR"
.IP "\f(CW(caar \fIs\fP)\fR"
.IP "\f(CW(cdar \fIs\fP)\fR"
.IP "\f(CW(cadar \fIs\fP)\fR"
.IP "\f(CW(caddr \fIs\fP)\fR"
.IP "\f(CW(cddar \fIs\fP)\fR"
.IP "\f(CW(cdadr \fIs\fP)\fR"
.br
These correspond to various compositions of
\fBcar\fR and \fBcdr\fR, \fIe.g.\fR,
.br
\f(CW(cadr \fIs\fP)\fR \(-> \f(CW(car (cdr \fIs\fP))\fR.
.IP "\f(CW(null \fIs\fP)\fR"
.br
Equivalent to \f(CW(eq \fIs\fP nil)\fR.
.IP "\f(CW(not \fIs\fP)\fR"
.br
Same as \fBnull\fR.
.IP "\f(CW(ff \fIs\fP)\fR"
.br
Returns the first atomic symbol in \fIs\fR.
.IP "\f(CW(subst \fIx y z\fP)\fR"
.br
Substitutes \fIx\fR for all occurrences of the atom \fIy\fR in \fIz\fR.
\fIx\fR and \fIz\fR are arbitrary s-expressions.
.IP "\f(CW(equal \fIx y\fP)\fR"
.br
Returns \fBt\fR if \fIx\fR and \fIy\fR are
the same s-expression, otherwise \fBnil\fR.
.IP "\f(CW(append \fIx y\fP)\fR"
.br
Creates a new list containing the elements of x and y,
which must both be lists.
.IP "\f(CW(member \fIx y\fP)\fR"
.br
Returns \fBt\fR if \fIx\fR is an element of the list \fIy\fR,
otherwise \fBnil\fR.
.IP "\f(CW(pair \fIx y\fP)\fR"
.br
Pairs each element of the lists \fIx\fR and \fIy\fR,
and returns a list of the resulting pairs. The number
of pairs in the result will equal the length of the
shorter of the two input lists.
.IP "\f(CW(assoc \fIx y\fP)\fR"
.br
Association list selector function.
\fIy\fR is a list of the
form \f(CW((\fIu1\fP \fIv1\fP) \fI...\fP (\fIuN\fP \fIvN\fP))\fR
where the \fIu\fR's are atomic. If \fIx\fR is
one of these, the corresponding pair \f(CW(\fIu\fP \fIv\fP)\fR
is returned, otherwise \fBnil\fR.
.IP "\f(CW(sublis \fIx y\fP)\fR"
.br
\fIx\fR is an association list.
Substitutes the values in \fIx\fR for the keys in \fIy\fR.
.IP "\f(CW(last \fIl\fP)\fR"
.br
Returns the last element of \fIl\fR.
.IP "\f(CW(reverse \fIl\fP)\fR"
.br
Returns a list that contains the elements in \fIl\fR,
in reverse order.
.IP "\f(CW(remove \fIe l\fP)\fR"
.br
Returns a copy of \fIl\fR with all
occurrences of the element \fIe\fR removed.
.IP "\f(CW(succ \fIx y\fP)\fR"
.br
Returns the element that immediately follows the atom \fIx\fR
in the list \fIy\fR. If \fIx\fR does not occur in \fIy\fR
or is the last element, \fBnil\fR is returned.
.IP "\f(CW(pred \fIx y\fP)\fR"
.br
Returns the element that immediately precedes the atom \fIx\fR
in the list \fIy\fR. If \fIx\fR does not occur in \fIy\fR
or is the first element, \fBnil\fR is returned.
.IP "\f(CW(before \fIx y\fP)\fR"
.br
Returns the list of elements occurring before y in x.
If \fIy\fR does not occur in \fIx\fR
or is the first element, \fBnil\fR is returned.
.IP "\f(CW(after \fIx y\fP)\fR"
.br
Returns the list of elements occurring after y in x.
If \fIy\fR does not occur in \fIx\fR
or is the last element, \fBnil\fR is returned.
.IP "\f(CW(plist \fIx\fP)\fR"
.br
Returns the property list for the atom \fIx\fR.
.IP "\f(CW(get \fIx i\fP)\fR"
.br
Returns the value stored on \fIx\fR's property list
under the indicator \fIi\fR.
.IP "\f(CW(putprop \fIx v i\fP)\fR"
.br
Stores the value \fIv\fR on \fIx\fR's property list under
the indicator \fIi\fR.
.IP "\f(CW(remprop \fIx i\fP)\fR"
.br
Remove the indicator \fIi\fR
and any associated value from \fIx\fR's property list.
.IP "\f(CW(mapcar \fIf l\fP)\fR"
.br
Applies the function \fIf\fR to each element of \fIl\fR and returns
the list of results.
.IP "\f(CW(apply \fIf args\fP)\fR"
.br
Calls \fIf\fR with the arguments \fIargs\fR, \fIe.g.\fR,
.ZB
(apply 'cons '(a (b)))
.ZE
is equivalent to
.ZB
(cons 'a '(b))
.ZE
.SH
Syntactic conventions.
.LP
Atoms take the following forms:
.IP "\fIRegular identifiers\fR"
.br
Atoms matching the regular expression
.br
.sp
.nf
\f(CW[_A-Za-z][-A-Za-z_0-9]*\fR
.fi
.sp
The initial value of an identifier is \fBnil\fR.
.IP "\fIIntegers\fR"
.br
Atoms matching the regular expression \f(CW[0-9][0-9]*\fR.
Integers are constants, \fIi.e.\fR, evaluate to themselves.
.IP "\fIWeird atoms\fR"
.br
Identifiers matching the regular expression \f(CW".*"\fR. Weird
atoms are not constants.
.LP
A semicolon introduces a comment, which continues for the rest
of the line.
.SH
Usage.
.LP
The command for running the interpreter is
.ZB
walk [ \fIfiles\fP ]
.ZE
on BSD UNIX and derivative systems, or
.ZB
awk -f walk [ \fIfiles\fP ]
.ZE
on UNIX System V.
The file name \f(CW\-\fR represen